package org.taobao.ibatiside.ui.wizard;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ComboBoxViewerCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.taobao.ibatiside.model.mapperv2.Discriminator;
import org.taobao.ibatiside.model.mapperv2.Mapperv2Factory;
import org.taobao.ibatiside.model.mapperv2.ResultMap;
import org.taobao.ibatiside.model.mapperv2.SubMap;
import org.taobao.ibatiside.ui.util.MiscHelper;
import org.taobao.ibatiside.ui.util.WorkspaceUtil;

public class NewDiscriminatorDialog extends TitleAreaDialog {
	private static final String[] P_RESULT_MAP = new String[]{"resultMap"};
	private static final String[] P_VALUE = new String[]{"value"};
	private Table table;
	private Text textNullValue;
	private Text textTypeHandler;
	private TableViewer tableViewer;
	private IStructuredContentProvider contentProvider;
	private ILabelProvider labelProvider;
	Discriminator discriminator;
	private Combo comboJavaType;
	private Combo combJDBCType;
	private Combo comboColumn;
	private String[] columItems;

	public NewDiscriminatorDialog(Shell parentShell) {
		super(parentShell);
	}
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("new discriminator");
	}


	@Override
	protected Control createDialogArea(Composite parent) {
		setMessage("create a discriminator for one resultmap");
		setTitle("discriminator");
		
		initProvider();
		
		discriminator = Mapperv2Factory.eINSTANCE.createDiscriminator();
		
		Composite area = (Composite) super.createDialogArea(parent);
		Composite container = new Composite(area, SWT.NONE);
		container.setLayout(new GridLayout(2, false));
		container.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		Group grpProperties = new Group(container, SWT.NONE);
		grpProperties.setText("Properties");
		grpProperties.setLayout(new GridLayout(2, false));
		GridData gd_grpProperties = new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1);
		gd_grpProperties.widthHint = 400;
		grpProperties.setLayoutData(gd_grpProperties);
		
		Label lblColumnName = new Label(grpProperties, SWT.NONE);
		lblColumnName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblColumnName.setText("Column Name");
		
		comboColumn = new Combo(grpProperties, SWT.READ_ONLY);
		comboColumn.setItems(columItems);
		comboColumn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		comboColumn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Label lblJavaType = new Label(grpProperties, SWT.NONE);
		lblJavaType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblJavaType.setAlignment(SWT.RIGHT);
		lblJavaType.setText("Java Type");
		
		comboJavaType = new Combo(grpProperties, SWT.READ_ONLY);
		comboJavaType.setItems(MiscHelper.MAPPING_JAVA_TYPE);
		comboJavaType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Label lblJdbcType = new Label(grpProperties, SWT.NONE);
		lblJdbcType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblJdbcType.setText("JDBC Type");
		
		combJDBCType = new Combo(grpProperties, SWT.READ_ONLY);
		combJDBCType.setItems(MiscHelper.JDBC_TYPE);
		combJDBCType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Label lblNullValue = new Label(grpProperties, SWT.NONE);
		lblNullValue.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblNullValue.setText("Null Value");
		
		textNullValue = new Text(grpProperties, SWT.BORDER);
		textNullValue.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Label lblTypeHandler = new Label(grpProperties, SWT.NONE);
		lblTypeHandler.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblTypeHandler.setText("Type Handler");
		
		textTypeHandler = new Text(grpProperties, SWT.BORDER);
		textTypeHandler.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				IType select_type = WorkspaceUtil.openType2(getParentShell(), BatisSettingModel.getActiveModel().getCurrentProject(), false);
				if (select_type != null){
					textTypeHandler.setText(select_type.getFullyQualifiedName());
				}
			}
		});
		textTypeHandler.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION);
		table = tableViewer.getTable();
		table.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.character == SWT.DEL){
					ISelection selection = tableViewer.getSelection();
					if (!selection.isEmpty()){
						SubMap sm = (SubMap) ((IStructuredSelection)selection).getFirstElement();
						discriminator.getSubMap().remove(sm);
						tableViewer.remove(sm);
					}
				}
			}
		});
		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				int line_pos = e.y / table.getItemHeight();
				if (line_pos > table.getItemCount()){
					//insert new
					SubMap sm = Mapperv2Factory.eINSTANCE.createSubMap();
					discriminator.getSubMap().add(sm);
					tableViewer.add(sm);
					int column_idx = e.x > table.getColumn(0).getWidth() ? 1 : 0;
					tableViewer.editElement(sm, column_idx);
				}
			}
		});
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
		tableViewerColumn.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null ? "" : ((SubMap)element).getValue();
			}
		});
		tableViewerColumn.setEditingSupport(new EditingSupport(tableViewer) {
			protected boolean canEdit(Object element) {
				return true;
			}
			protected CellEditor getCellEditor(Object element) {
				return new TextCellEditor(table);
			}
			protected Object getValue(Object element) {
				return StringUtils.defaultString(((SubMap)element).getValue());
			}
			protected void setValue(Object element, Object value) {
				String str = (String) value;
				if (StringUtils.isNotBlank(str)){
					((SubMap)element).setValue(str);
					tableViewer.update(element, P_VALUE);
				}
			}
		});
		TableColumn tblclmnValue = tableViewerColumn.getColumn();
		tblclmnValue.setWidth(92);
		tblclmnValue.setText("Value");
		
		TableViewerColumn tableViewerColumn_1 = new TableViewerColumn(tableViewer, SWT.NONE);
		tableViewerColumn_1.setEditingSupport(new EditingSupport(tableViewer) {
			protected boolean canEdit(Object element) {
				return true;
			}
			protected CellEditor getCellEditor(Object element) {
				ComboBoxViewerCellEditor resultMapCellEditor = new ComboBoxViewerCellEditor(table);
				resultMapCellEditor.setContentProvider(contentProvider);
				resultMapCellEditor.setLabelProvider(labelProvider);
				resultMapCellEditor.setInput(BatisSettingModel.getActiveModel().getSqlmap().getResultMap());
				return resultMapCellEditor;
			}
			protected Object getValue(Object element) {
				return ((SubMap)element).getResultMap();
			}
			protected void setValue(Object element, Object value) {
				if (value != null){
					((SubMap)element).setResultMap((ResultMap) value);
					tableViewer.update(element, P_RESULT_MAP);
				}
			}
		});
		tableViewerColumn_1.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null || ((SubMap)element).getResultMap() == null ? "" : ((SubMap)element).getResultMap().getId();
			}
		});
		TableColumn tblclmnResultmap = tableViewerColumn_1.getColumn();
		tblclmnResultmap.setWidth(143);
		tblclmnResultmap.setText("ResultMap");
		tableViewer.setContentProvider(new ArrayContentProvider());
		tableViewer.setInput(discriminator.getSubMap());
		return area;
	}

	private void initProvider() {
		contentProvider = new ArrayContentProvider();
		labelProvider = new LabelProvider(){
			@Override
			public String getText(Object element) {
				return ((ResultMap)element).getId();
			}
		};
	}

	/**
	 * Create contents of the button bar.
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
				true);
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}
	@Override
	protected void okPressed() {
		if (StringUtils.isBlank(comboColumn.getText())){
			setErrorMessage("column is required!");
			return;
		}
		discriminator.setColumn(comboColumn.getText());
		if (StringUtils.isNotBlank(comboJavaType.getText())){
			discriminator.setJavaType(comboJavaType.getText());
		}
		if (StringUtils.isNotBlank(combJDBCType.getText())){
			discriminator.setJdbcType(combJDBCType.getText());
		}
		if (StringUtils.isNotBlank(textNullValue.getText())){
			discriminator.setNullValue(textNullValue.getText().trim());
		}
		if (StringUtils.isNotBlank(textTypeHandler.getText())){
			discriminator.setTypeHandler(textTypeHandler.getText().trim());
		}
		if (discriminator.getSubMap().size() < 1){
			setErrorMessage("No submap!");
			return;
		}
		super.okPressed();
	}
	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(668, 442);
	}
	public void setResultWrappers(String[] columns) {
		columItems = columns;
	}
}
